package mtm.ui.list;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import mtm.constants.Constants;
import mtm.date.MtmDate;
import mtm.db.DatabaseHandler;
import mtm.db.Job;
import mtm.db.RepeatJob;
import mtm.ui.MainFrame;
import mtm.ui.job.JobFrame;
import mtm.ui.job.RepeatJobFrame;
import mtm.ui.panel.WeekPanel;


/**
 * Custom list to display color, icon and text in a list
 * @author CondorHero89
 *
 */
public class JobList extends JList {

	private DefaultListModel model;
	public static int MAX_LIST_SIZE = 4;
	protected int numOfJobs = 0;

	protected int date;
	public static final int NO_DATE = 0;
	
	/**
	 * Constructor
	 */
	public JobList(int date) {
		super();
		model = new DefaultListModel();
		setModel(model);
		setCellRenderer(new JobCellRender());
		
		// set date
		this.date = date;
		
		// set border
		setBorder(new LineBorder(Color.RED, 1, true));

		// setup title
		setupList(date);

		// add listener for event maximum number of items reached
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// switch to week view mode when double click on date title
				if (e.getClickCount() == 2) {
					if (getSelectedIndex() == 0) {
						if (hasJob()) {
							JobItem item = (JobItem) model.get(1);
							MtmDate dateOfJob = item.getJob().getStartTime();
							
							// find first day of selected week
							dateOfJob.addDate(-(dateOfJob.getDay() - 1));
							dateOfJob.setHours(0);
							dateOfJob.setMinutes(0);
							
							// load jobs
							WeekPanel.getInstance().displayJobsInWeek(dateOfJob);
							
							// switch to WeekView mode
							MainFrame.getInstance().setJobView(Constants.WEEK_VIEW);
						} else {
							JOptionPane.showMessageDialog(null, "Chưa có việc để làm ^^");
						}
					}
				}
				
				// perform action on a selected item
				else if (e.getClickCount() == 1) {
					// only perform when this item is not date title
					if (getSelectedIndex() != 0) {
						JobItem item = (JobItem) getSelectedValue();
						if (item != null && item.getJob() != null) {
							Job job = item.getJob();
							if (job.isGeneratedJob()) {
								RepeatJob repeatJob = DatabaseHandler.getInstance().getRepeatJob(job.getParentId());
								new RepeatJobFrame(repeatJob);
							} else {
								new JobFrame(job);
							}
						}
					}
				}
			}
		});
	}

	
	/**
	 * Add item to list, alert when number of items is greater than maximum 
	 * list size
	 * 
	 * @param item
	 */
	public void addItem(JobItem item) {
		numOfJobs++;
		
		if (numOfJobs <= MAX_LIST_SIZE) {
			model.set(numOfJobs, item);
		} else if (numOfJobs == MAX_LIST_SIZE + 1) {
			model.set(MAX_LIST_SIZE + 1, new JobItem(Color.WHITE, "<html><a href=#>Xem chi tiết</a></html>"));
			model.addElement(item);
		} else {
			model.addElement(item);
		}
	}

	
	/**
	 * Remove item of list
	 */
	public void removeSelectedItem() {
		removeIndex(getSelectedIndex());
	}
	
	
	protected void removeIndex(int index) {
		if (numOfJobs > MAX_LIST_SIZE) {
			for (int i = index; i < MAX_LIST_SIZE; ++i) {
				model.set(i, model.get(i + 1));
			}
			model.set(MAX_LIST_SIZE, model.get(MAX_LIST_SIZE + 2));
			if (numOfJobs == MAX_LIST_SIZE + 1) {
				model.remove(MAX_LIST_SIZE + 2);
				model.set(MAX_LIST_SIZE + 1, new JobItem());
			} else {
				for (int i = MAX_LIST_SIZE + 2; i < numOfJobs + 1; ++i) {
					model.set(i, model.get(i + 1));
				}
				model.remove(numOfJobs + 1);
			}
		} else {
			for (int i = index; i < numOfJobs; ++i) {
				model.set(i, model.get(i + 1));
			}
			model.set(numOfJobs, new JobItem());
		}
		
		numOfJobs--;
	}
	
	
	/**
	 * Remove a job item from list
	 * @param job
	 */
	public void removeJob(Job job) {
		JobItem currentItem;
		int index = -1;
		for (int i = 1; i < numOfJobs && i != MAX_LIST_SIZE + 1; ++i) {
			currentItem = (JobItem) model.get(i);
			if (currentItem.getId() == job.getId()) {
				index = i;
			}
		}
		
		removeIndex(index);
	}
	
	
	/**
	 * Remove generated job of the RepeatJob has this parentId
	 * @param parentId
	 */
	public void removeRepeatJob(int parentId) {
		JobItem currentItem;
		for (int i = 1; i <= numOfJobs && i != MAX_LIST_SIZE + 1; ++i) {
			currentItem = (JobItem) model.get(i);
			if (currentItem.getJob().getParentId() == parentId) {
				removeIndex(i);
				return;
			}
		}
	}
	
	
	/**
	 * Sset date title
	 * @param date
	 */
	public void setDateTitle(int date) {
		this.date = date;
		// create title item
		JobItem li = new JobItem(Color.cyan, "" + date);
		li.setIcon(new ImageIcon(Constants.DEFAULT_JOB_ICON));
		li.setDragable(false);
		li.setHasToolTip(false);
		model.set(0, li);
	}
	
	
	/**
	 *  Create title and an empty list
	 * @param date
	 */
	protected void setupList(int date) {
		// add title 
		JobItem li = null;
		if (date == NO_DATE) {
			li = new JobItem(Color.white, " ");
		} else {
			li = new JobItem(Color.cyan, "" + date);
		}
		li.setDragable(false);
		li.setHasToolTip(false);
		if (date != NO_DATE) {
			li.setIcon(new ImageIcon(Constants.DEFAULT_JOB_ICON));
		}
		model.addElement(li);
		
		// add empty items
		for (int i = 1; i < MAX_LIST_SIZE + 2; ++i) {
			model.addElement(new JobItem());
		}
	}
	
	
	/**
	 * Remove all jobs from this list
	 */
	public void removeAllJobs() {
		model.clear();
		numOfJobs = 0;
		setupList(NO_DATE);
	}
	
	
//	/**
//	 * Remove an item which is correlative with a job
//	 * @param job
//	 */
//	public void removeJob(Job job) {
//		JobItem removedItem;
//		int removedIndex = 0;
//		for (int i = 1; i < numOfJobs; ++i) {
//			removedItem = (JobItem) model.get(i);
//			if (removedItem.getId() == job.getId()) {
//				removedIndex = i;
//				break;
//			}
//		}
//		
//		numOfJobs--;
//		for (int i = removedIndex; i < numOfJobs; ++i) {
//			model.set(i, model.getElementAt(i + 1));
//		}
//		
//		if (numOfJobs >= MAX_LIST_SIZE) {
//			model.set(MAX_LIST_SIZE, new JobItem(Color.WHITE, "<html><a href=#>Xem chi tiết</a></html>"));
//		}
//	}
	
	
	/**
	 * Update a job in this list
	 * @param job
	 */
	public void updateJob(Job job) {
		int size = model.getSize();
		JobItem currentItem;
		for (int i = 1; i < size; ++i) {
			currentItem = (JobItem) model.get(i);
			if (currentItem.getId() == job.getId()) {
				model.set(i, new JobItem(job));
				break;
			}
		}
	}
	
	
	/**
	 * Check if this label has some jobs display on it or not?
	 * @return
	 */
	public boolean hasJob() {
		return numOfJobs >= 1;
	}
	
	
	/***
	 * Return date of this label
	 * @return
	 */
	public int getDate() {
		return this.date;
	}
}
